package com.gitee.wsl.coroutines.job.trigger

import com.gitee.wsl.coroutines.job.IJobExecutionContext
import com.gitee.wsl.coroutines.job.exception.JobExecutionException
import com.gitee.wsl.coroutines.job.exception.SchedulerException
import com.gitee.wsl.time.calendar.Calendar
import com.gitee.wsl.coroutines.job.trigger.ITrigger.ECompletedExecutionInstruction
import kotlin.time.ExperimentalTime
import kotlin.time.Instant


@OptIn(ExperimentalTime::class)
interface IOperableTrigger : IMutableTrigger {
    /**
     * This method should not be used by the Quartz client.<br></br>
     * Called when the `IScheduler` has decided to 'fire' the trigger
     * (execute the associated `Job`), in order to give the
     * `Trigger` a chance to update itself for its next triggering (if
     * any).
     *
     * @see .executionComplete
     */
    fun triggered(calendar: Calendar)

    /**
     * This method should not be used by the Quartz client.<br></br>
     * Called by the scheduler at the time a `Trigger` is first added
     * to the scheduler, in order to have the `Trigger` compute its
     * first fire time, based on any associated calendar.<br></br>
     * After this method has been called, `getNextFireTime()` should
     * return a valid answer.
     *
     * @return the first time at which the `Trigger` will be fired by
     * the scheduler, which is also the same value
     * `getNextFireTime()` will return (until after the first
     * firing of the `Trigger`).
     */
    fun computeFirstFireTime(aCalendar: Calendar): Instant?

    /**
     * This method should not be used by the Quartz client.<br></br>
     * Called after the `Scheduler` has executed the
     * `[com.helger.quartz.IJobDetail]` associated with the
     * `Trigger` in order to get the final instruction code from the
     * trigger.
     *
     * @param aContext
     * is the `JobExecutionContext` that was used by the
     * `Job`'s`execute(xx)` method.
     * @param result
     * is the `JobExecutionException` thrown by the
     * `Job`, if any (may be null).
     * @return one of the `CompletedExecutionInstruction` constants.
     * @see .triggered
     */
    
    fun executionComplete(
        aContext: IJobExecutionContext,
         result: JobExecutionException?,
    ): ECompletedExecutionInstruction?

    /**
     * This method should not be used by the Quartz client.<br></br>
     * To be implemented by the concrete classes that extend this class.<br></br>
     * The implementation should update the `Trigger`'s state based on
     * the MISFIRE_INSTRUCTION_XXX that was selected when the `Trigger`
     * was created.
     */
    fun updateAfterMisfire(cal: Calendar)

    /**
     * This method should not be used by the Quartz client.<br></br>
     * To be implemented by the concrete class.<br></br>
     * The implementation should update the `Trigger`'s state based on
     * the given new version of the associated `Calendar` (the state
     * should be updated so that it's next fire time is appropriate given the
     * Calendar's new settings).
     *
     * @param cal
     */
    fun updateWithNewCalendar(cal: Calendar, misfireThreshold: Long)

    /**
     * Validates whether the properties of the `JobDetail` are valid
     * for submission into a `Scheduler`.
     *
     * @throws IllegalStateException
     * if a required property (such as Name, Group, Class) is not set.
     */
    @Throws(SchedulerException::class)
    fun validate()

    /**
     * This method should not be used by the Quartz client.<br></br>
     * Usable by `[com.helger.quartz.spi.IJobStore]`
     * implementations, in order to facilitate 'recognizing' instances of fired
     * `Trigger` s as their jobs complete execution.
     */
    
    var fireInstanceId: String?

    //fun setNextFireTime(nextFireTime: Instant)

    //fun setPreviousFireTime(previousFireTime: Instant)

}
